package top.lixunda.commerce.common.core.controller.wrapper;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * @author LiXunda
 * @version time:2019/10/14 9:50
 * <p>
 * 本程序吧SQL语句分为三个部分，数据部分，条件部分，其他部分
 * 数据部分是select或者update的数据，可以选择select的字段以及update更新的字段和值
 * 条件部分是由树形结构进行保存，负责记录查询的条件，可以进行嵌套
 * 其他部分是除了数据部分和条件部分之外的其他部分，包括groupBy，having，orderBy等
 * 本类为其他部分
 */
@SuppressWarnings("ALL")
@Slf4j
public class OtherBlock implements IOtherBlock {

    @JsonIgnore
    public static final String ORDER_BY_ASC = "ASC";

    @JsonIgnore
    public static final String ORDER_BY_DESC = "DESC";

    private Map<String, String> orderBy = new HashMap<>();

    private String having;

    private Set<String> groupBy = new HashSet<>();

    private Long[] page = new Long[2];

    public Long[] getPage() {
        return page.clone();
    }

    public void setPage(Long[] page) {
        this.page = page.clone();
    }


    public Map<String, String> getOrderBy() {
        return orderBy;
    }

    public OtherBlock setOrderBy(Map<String, String> orderBy) {
        this.orderBy = orderBy;
        return this;
    }

    public String getHaving() {
        return having;
    }

    public OtherBlock setHaving(String having) {
        this.having = having;
        return this;
    }

    public Set<String> getGroupBy() {
        return groupBy;
    }

    public OtherBlock setGroupBy(Set<String> groupBy) {
        this.groupBy = groupBy;
        return this;
    }

    public OtherBlock addOrderBy(String column, String type) {
        this.orderBy.put(column, type);
        return this;
    }

    @Override
    public IOtherBlock groupBy(String... column) {
        this.groupBy.addAll(Arrays.asList(column));
        return this;
    }

    @Override
    public IOtherBlock orderBy(Map<String, String> map) {
        this.orderBy.putAll(map);
        return this;
    }

    @Override
    public IOtherBlock orderBy(String column, String type) {
        if (!(ORDER_BY_ASC.equals(type) || ORDER_BY_DESC.equals(type))) {
            log.warn("the parameter named type of orderBy method must be ORDER_TYPE_ASC or ORDER_TYPE_AESC");
            return this;
        }
        this.orderBy.put(column, type);
        return this;
    }

    @Override
    public IOtherBlock orderByAsc(String... column) {
        for (String s : column) {
            this.orderBy.put(s, ORDER_BY_ASC);
        }
        return this;
    }

    @Override
    public IOtherBlock orderByDesc(String... column) {
        for (String s : column) {
            this.orderBy.put(s, ORDER_BY_DESC);
        }
        return this;
    }

    @Override
    public IOtherBlock having(String column) {
        this.setHaving(column);
        return this;
    }


    @Override
    public IOtherBlock page(long current, long count) {
        if (current < 0) {
            log.warn("the page start must to be greater than 0, reset it start from 0");
            current = 0;
        }
        if (count < 0) {
            log.warn("thie count of data must be greater than 0, reset the count to 0");
            count = 0;
        }
        this.page[0] = current;
        this.page[1] = count;
        return this;
    }
}
